package com.hqd.ch03.v31.web.method;


import com.hqd.ch03.utils.ClassUtils;
import com.hqd.ch03.utils.ReflectionUtils;
import com.hqd.ch03.v31.core.MethodParameter;
import lombok.Data;

import java.lang.reflect.Method;

/**
 * 处理方法
 */
@Data
public class HandlerMethod {
    /**
     * 目标对象
     */
    private final Object bean;
    /**
     * 目标对象类型
     */
    private final Class<?> beanType;
    /**
     * 目标方法
     */
    private final Method method;
    /**
     * 方法参数
     */
    private MethodParameter[] parameters;
    private HandlerMethod resolvedFromHandlerMethod;


    public HandlerMethod(Object bean, String methodName, Class<?>... parameterTypes) throws NoSuchMethodException {
        this.bean = bean;
        this.beanType = ClassUtils.getUserClass(bean);
        this.method = bean.getClass().getMethod(methodName, parameterTypes);
    }

    public HandlerMethod(Object bean, Method method) {
        this.bean = bean;
        this.beanType = ClassUtils.getUserClass(bean);
        this.method = method;
    }

    private HandlerMethod(HandlerMethod handlerMethod, Object handler) {
        this.bean = handler;
        this.beanType = handlerMethod.beanType;
        this.method = handlerMethod.method;
        this.resolvedFromHandlerMethod = handlerMethod.resolvedFromHandlerMethod;
        ReflectionUtils.makeAccessible(this.method);
        this.parameters = initMethodParameters();
    }


    private MethodParameter[] initMethodParameters() {
        int count = this.method.getParameterCount();
        MethodParameter[] result = new MethodParameter[count];
        for (int i = 0; i < count; i++) {
            result[i] = new MethodParameter(this.method, i);
        }
        return result;
    }

    public HandlerMethod createWithResolvedBean() {
        return new HandlerMethod(this, this.bean);
    }
}
